
<template>
    <div class="StockChart">
        <div class="ma" v-if="details.transaction">
            <div class="list">
                <div class="item" :style="{ color: ma5Color }">ma5: {{ details.transaction.at(-1).ma5 }}</div>
                <div class="item" :style="{ color: ma10Color }">ma10: {{ details.transaction.at(-1).ma10 }}</div>
                <div class="item" :style="{ color: ma20Color }">ma20: {{ details.transaction.at(-1).ma20 }}</div>
                <div class="item" :style="{ color: ma30Color }">ma30: {{ details.transaction.at(-1).ma30 }}</div>
                <div class="item" :style="{ color: ma60Color }">ma60: {{ details.transaction.at(-1).ma60 }}</div>
                <div class="item" :style="{ color: ma120Color }">ma120: {{ details.transaction.at(-1).ma120 }}</div>
                <div class="item" :style="{ color: ma250Color }">ma250: {{ details.transaction.at(-1).ma250 }}</div>
            </div>
        </div>
        <div class="echarts">
            <Echarts :option="option" @eChartReady="eChartReady" />
        </div>
    </div>
</template>
  
<script setup>
import { reactive, watch, computed } from "vue"

import $color from "@/color"
import Echarts from "@/components/Echarts/Echarts.vue"


const props = defineProps({
    details: {
        type: Object,
        default: {}
    }
})

const option = reactive({})

let chart = null

const textColor = "#6a6c78"
const borderColor = "#202020"
const borderWidth = 0.5

const ma5Color = "#fff"
const ma10Color = "#cfa968"
const ma20Color = "#a156bb"
const ma30Color = "#cea766"
const ma60Color = "#a41322"
const ma90Color = "#d08156"
const ma120Color = "#5c75ab"
const ma250Color = "#65b9d5"

watch(() => props.details, async (details) => {
    if (!details.code) return false

    let { code = "", transaction = [], calculate: { macd: { macd = [] }, kdj: { k = [], d = [] } }, analysis = {} } = details

    const axisCommon = { axisLine: { show: false }, splitLine: { show: false }, axisTick: { show: false }, axisLabel: { show: false } }

    // 用 markArea 标注背离
    const markAreaDivergence = (() => {
        let result = {
            markArea: {
                silent: true,
                data: []
            }
        }
        let { bottom, top } = analysis.divergence

        if (bottom) {
            let style = {
                label: {
                    position: "inside",
                    formatter: `底背离(${bottom.range.length})`,
                    fontWeight: "bold",
                    fontSize: 10,
                    color: $color.downColor
                },
                itemStyle: {
                    borderWidth: 2,
                    borderType: "dotted",
                    borderColor: $color.downBorderColor,
                    color: $color.downBackgroundColor
                },
            }
            result.markArea.data.push([
                { xAxis: bottom.range.at(0), ...style },
                { xAxis: bottom.range.at(-1), ...style }
            ])
        }
        if (top) {
            let style = {
                label: {
                    position: "inside",
                    formatter: `顶背离(${top.range.length})`,
                    fontWeight: "bold",
                    fontSize: 10,
                    color: $color.upColor
                },
                itemStyle: {
                    borderWidth: 2,
                    borderType: "dotted",
                    borderColor: $color.upBorderColor,
                    color: $color.upBackgroundColor
                },
            }
            result.markArea.data.push([
                { xAxis: top.range.at(0), ...style },
                { xAxis: top.range.at(-1), ...style }
            ])
        }
        return result
    })()

    // 用 markLine 标注背离
    const markLineDivergence = (() => {
        let result = {
            markLine: {
                silent: true,
                data: [],
                symbolSize: 8
            }
        }
        let { bottom, top } = analysis.divergence
        if (bottom) {
            let style = {
                lineStyle: {
                    type: 'dotted',
                    color: $color.downColor
                }
            }
            result.markLine.data.push([
                { coord: [bottom.range.at(0), transaction.at(bottom.range.at(0)).low], ...style }, // 第一根柱子的低点坐标（x轴索引0，y轴值10）
                { coord: [bottom.range.at(-1), transaction.at(bottom.range.at(-1)).low], ...style } // 最后一根柱子的低点坐标（x轴索引3，y轴值5）
            ])
        }
        if (top) {
            let style = {
                lineStyle: {
                    type: 'dotted',
                    color: $color.upColor
                }
            }
            result.markLine.data.push([
                { coord: [top.range.at(0), transaction.at(top.range.at(0)).high], ...style }, // 第一根柱子的低点坐标（x轴索引0，y轴值10）
                { coord: [top.range.at(-1), transaction.at(top.range.at(-1)).high], ...style } // 最后一根柱子的低点坐标（x轴索引3，y轴值5）
            ])
        }
        return result
    })()

    let timeData = [] // 日期 ["2012-02-04"]
    let transactionData = [] // K线 [open, close, low, high]
    let macdData = [] // macd [-3, -2, -1, 1]
    let kdjData = { k: [], d: [] } // kdj [-3, -2, -1, 1]

    let ma5Data = [] // 5均线
    let ma10Data = [] // 10均线
    let ma20Data = [] // 20均线
    let ma30Data = [] // 30均线
    let ma60Data = [] // 60均线
    let ma90Data = [] // 90均线
    let ma120Data = [] // 120均线
    let ma250Data = [] // 240均线

    let volumeData = [] // 成交量 [257841651]
    let volume5Data = [] // 5成交量
    let volume10Data = [] // 10成交量

    transaction.forEach(({ time, open, close, low, high, volume, ma5, ma10, ma20, ma30, ma60, ma90, ma120, ma250, volume5, volume10 }, index) => {
        let macdItem = macd[index]

        timeData.push(index)
        // timeData.push(time)
        transactionData.push([open, close, low, high])
        macdData.push({ value: macdItem, itemStyle: { color: macdItem > 0 ? $color.upColor : $color.downColor } })

        kdjData.k.push(k[index])
        kdjData.d.push(d[index])

        ma5Data.push(ma5)
        ma10Data.push(ma10)
        ma20Data.push(ma20)
        ma30Data.push(ma30)
        ma60Data.push(ma60)
        ma90Data.push(ma90)
        ma120Data.push(ma120)
        ma250Data.push(ma250)

        volumeData.push({ value: volume, itemStyle: { color: open < close ? $color.upColor : $color.downColor } })
        volume5Data.push(volume5 * 100)
        volume10Data.push(volume10 * 100)
    })

    Object.assign(option, {
        color: [ma5Color, ma10Color, ma20Color, ma30Color, ma60Color, ma90Color, ma120Color, ma250Color],
        animation: false,
        tooltip: {
            trigger: "axis",
            triggerOn: "click",
            axisPointer: {
                type: "cross",
                label: {
                    show: false,
                    formatter(params) {
                        return transaction[params.value]?.time
                    }
                }
            },
            position: {
                top: 30
            },
            backgroundColor: "rgba(22, 25, 34, 0.8)",
            borderWidth: 0,
            textStyle: {
                color: textColor,
                lineHeight: 100,
            },
            confine: true
        },
        dataZoom: [{
            type: 'inside',
            xAxisIndex: "all",
            // start: 100 - ((60 / transaction.length) * 100),
            start: 0,
            end: 100,
            minSpan: 25
        }],
        axisPointer: {
            link: [
                { xAxisIndex: 'all' }
            ]
        },
        // 定义四个grid区域，分别放置四个子图
        grid: [
            { top: '0%', left: 1, right: 1, height: '74%', show: true, backgroundColor: "#161922", borderWidth: 0 }, // 蜡烛图
            { top: '75%', left: 0, right: 0, height: '9%', show: true, backgroundColor: "#161922", borderWidth: 0 }, // 第一个柱状图
            { top: '85%', left: 0, right: 0, height: '9%', show: true, backgroundColor: "#161922", borderWidth: 0 }, // 第二个柱状图
            { top: '95%', left: 0, right: 0, height: '5%', show: true, backgroundColor: "#161922", borderWidth: 0 }  // 折线图
        ],
        xAxis: [
            { type: 'category', data: timeData, gridIndex: 0, ...axisCommon },
            { type: 'category', data: timeData, gridIndex: 1, ...axisCommon },
            { type: 'category', data: timeData, gridIndex: 2, ...axisCommon },
            { type: 'category', data: timeData, gridIndex: 3, ...axisCommon }
        ],
        yAxis: [
            { type: 'value', gridIndex: 0, scale: true, ...axisCommon, boundaryGap: false, splitNumber: 5, splitLine: { lineStyle: { width: borderWidth, color: borderColor } }, axisLabel: { inside: true, fontSize: 9, color: textColor } },
            { type: 'value', gridIndex: 1, ...axisCommon },
            { type: 'value', gridIndex: 2, ...axisCommon },
            { type: 'value', gridIndex: 3, ...axisCommon }
        ],
        series: [
            // 蜡烛图系列
            { name: 'serie', type: 'candlestick', xAxisIndex: 0, yAxisIndex: 0, data: transactionData, ...markAreaDivergence, ...markLineDivergence, itemStyle: { normal: { color: $color.downColor, color0: $color.upColor, borderColor: $color.downColor, borderColor0: $color.upColor } } },
            { name: 'ma5', type: 'line', xAxisIndex: 0, yAxisIndex: 0, data: ma5Data, silent: true, lineStyle: { width: 1 }, showSymbol: false },
            { name: 'ma10', type: 'line', xAxisIndex: 0, yAxisIndex: 0, data: ma10Data, silent: true, lineStyle: { width: 1 }, showSymbol: false },
            { name: 'ma20', type: 'line', xAxisIndex: 0, yAxisIndex: 0, data: ma20Data, silent: true, lineStyle: { width: 1 }, showSymbol: false },
            { name: 'ma30', type: 'line', xAxisIndex: 0, yAxisIndex: 0, data: ma30Data, silent: true, lineStyle: { width: 1 }, showSymbol: false },
            { name: 'ma60', type: 'line', xAxisIndex: 0, yAxisIndex: 0, data: ma60Data, silent: true, lineStyle: { width: 1 }, showSymbol: false },
            { name: 'ma90', type: 'line', xAxisIndex: 0, yAxisIndex: 0, data: ma60Data, silent: true, lineStyle: { width: 1 }, showSymbol: false },
            { name: 'ma120', type: 'line', xAxisIndex: 0, yAxisIndex: 0, data: ma120Data, silent: true, lineStyle: { width: 1 }, showSymbol: false },
            { name: 'ma250', type: 'line', xAxisIndex: 0, yAxisIndex: 0, data: ma250Data, silent: true, lineStyle: { width: 1 }, showSymbol: false },

            // 第一个柱状图系列
            { name: 'macd', type: 'bar', xAxisIndex: 1, yAxisIndex: 1, data: macdData, barWidth: 1, ...markAreaDivergence },

            // 折线图系列
            { name: 'kdj-k', type: 'line', xAxisIndex: 2, yAxisIndex: 2, data: kdjData.k, silent: true, lineStyle: { width: 1, color: ma5Color }, showSymbol: false },
            { name: 'kdj-d', type: 'line', xAxisIndex: 2, yAxisIndex: 2, data: kdjData.d, silent: true, lineStyle: { width: 1, color: ma10Color }, showSymbol: false, markLine: { silent: true, symbol: 'none', label: { show: false }, data: [{ xAxisIndex: 2, yAxisIndex: 2, yAxis: 80, lineStyle: { color: $color.upColor, type: 'dashed' } }, { xAxisIndex: 2, yAxisIndex: 2, yAxis: 20, lineStyle: { color: $color.downColor, type: 'dashed' } }] } },

            // 状图系列
            { name: 'volume', type: 'bar', xAxisIndex: 3, yAxisIndex: 3, data: volumeData, silent: true },
            { name: 'volume5', type: 'line', xAxisIndex: 3, yAxisIndex: 3, data: volume5Data, silent: true, lineStyle: { width: 1, color: ma5Color }, showSymbol: false },
            { name: 'volume10', type: 'line', xAxisIndex: 3, yAxisIndex: 3, data: volume10Data, silent: true, lineStyle: { width: 1, color: ma10Color }, showSymbol: false },
        ],

    })

}, { immediate: true, deep: true })




const eChartReady = (e) => {
    chart = e
}

const dataZoomToggle = () => {
    dataZoomToggle.zoom = !dataZoomToggle.zoom

    chart.dispatchAction(
        dataZoomToggle.zoom ? {
            type: "dataZoom",
            start: 85,
            end: 100
        } : {
            type: "dataZoom",
            start: 0,
            end: 100
        })
}

defineExpose({
    dataZoomToggle
})

</script>


<style lang="scss" scoped>
.StockChart {
    height: 100%;

    >.ma {
        position: absolute;
        z-index: 1;
        left: 0;
        top: 0;
        width: 100%;
        background: linear-gradient(to bottom, #161922, rgba(0, 0, 0, 0));
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;

        &::-webkit-scrollbar {
            display: none;
        }

        >.list {
            padding: 0 20upx;
            white-space: nowrap;

            >.item {
                display: inline-block;
                margin-right: 15upx;
                text-align: center;
                font-size: 18upx;
            }
        }
    }

    >.echarts {
        position: relative;
        height: 100%;
    }

}
</style>
  